package com.aiyige.location;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;

import com.aiyige.base.api.ApiManager;
import com.aiyige.base.api.ResponseCode;
import com.aiyige.location.model.LocationData;
import com.aiyige.setup.model.SetupInfo;
import com.aiyige.setup.util.SetupUtil;
import com.aiyige.utils.ErrorUtil;
import com.aiyige.utils.RetrofitUtil;
import com.alibaba.fastjson.JSON;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class LocationService extends Service implements AMapLocationListener {
    public static final String ACTION_LOCATION_FINISH = "com.aiyige.action.ACTION_LOCATION_FINISH";
    public static final String EXTRA_LOCATION_DATA = "com.aiyige.extra.EXTRA_LOCATION_DATA";


    private AMapLocationClient aMapLocationClient = null;
    private AMapLocationClientOption aMapLocationClientOption = null;

    public LocationService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        aMapLocationClient = new AMapLocationClient(this);
        aMapLocationClient.setLocationListener(this);
        aMapLocationClientOption = new AMapLocationClientOption();
        aMapLocationClientOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        aMapLocationClientOption.setOnceLocation(true);
//        aMapLocationClientOption.setOnceLocationLatest(true);
        aMapLocationClientOption.setNeedAddress(true);
        aMapLocationClient.setLocationOption(aMapLocationClientOption);
        aMapLocationClient.setLocationListener(this);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        aMapLocationClient.startLocation();
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        aMapLocationClient.stopLocation();
        aMapLocationClient.onDestroy();
        super.onDestroy();
    }


    public static void startLocation(Context context) {
        startLocation(context, false);
    }

    public static void startLocation(Context context, boolean flushCache) {
        if (flushCache) {
            SetupUtil.flushSetupInfoCache();
        }
        context.startService(new Intent(context, LocationService.class));
    }

    public static LocationData obtainLocationData(Intent intent) {
        return intent.getParcelableExtra(EXTRA_LOCATION_DATA);
    }

    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (aMapLocation.getErrorCode() == 0) {
            LocationData locationData = new LocationData();
            locationData.setLatitude(aMapLocation.getLatitude());
            locationData.setLongitude(aMapLocation.getLongitude());
            locationData.setAccuracy(aMapLocation.getAccuracy());
            locationData.setAltitude(aMapLocation.getAltitude());
            locationData.setSpeed(aMapLocation.getSpeed());
            locationData.setBearing(aMapLocation.getBearing());
            locationData.setBuildingId(aMapLocation.getBuildingId());
            locationData.setFloor(aMapLocation.getFloor());
            locationData.setAddress(aMapLocation.getAddress());
            locationData.setCountry(aMapLocation.getCountry());
            locationData.setProvince(aMapLocation.getProvince().replace("省", ""));
            locationData.setCity(aMapLocation.getCity().replace("市", ""));
            locationData.setDistrict(aMapLocation.getDistrict());
            locationData.setStreet(aMapLocation.getStreet());
            locationData.setStreetNum(aMapLocation.getStreetNum());
            locationData.setCityCode(aMapLocation.getCityCode());
            locationData.setAdCode(aMapLocation.getAdCode());
            locationData.setPoiName(aMapLocation.getPoiName());
            locationData.setAoiName(aMapLocation.getAoiName());
            locationData.setGpsAccuracyStatus(aMapLocation.getGpsAccuracyStatus());
            locationData.setLocationType(aMapLocation.getLocationType());
            locationData.setLocationDetail(aMapLocation.getLocationDetail());
            locationData.setErrorInfo(aMapLocation.getErrorInfo());
            locationData.setErrorCode(aMapLocation.getErrorCode());
            locationData.setSuccess(true);
            Intent intent = new Intent(ACTION_LOCATION_FINISH);
            intent.putExtra(EXTRA_LOCATION_DATA, locationData);
            sendBroadcast(intent);
        } else {
            fallbackLocation();
        }
    }

    public void fallbackLocation() {
        SetupInfo cachedSetupInfo = SetupUtil.getCachedSetupInfo();
        if (cachedSetupInfo != null) {
            Intent intent = new Intent(ACTION_LOCATION_FINISH);
            intent.putExtra(EXTRA_LOCATION_DATA, SetupUtil.convertSetupInfoToLocationData(cachedSetupInfo));
            sendBroadcast(intent);
        } else {
            ApiManager.getService().setupInfo().enqueue(new Callback<ResponseBody>() {
                @Override
                public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                    try {
                        if (response.code() != ResponseCode.OK) {
                            throw new Exception(ErrorUtil.extractMessageFromErrorResponse(response));
                        }
                        String json = RetrofitUtil.getResponseBodyAsString(response);
                        SetupInfo setupInfo = JSON.parseObject(json, SetupInfo.class);
                        SetupUtil.cacheSetupInfo(setupInfo);
                        Intent intent = new Intent(ACTION_LOCATION_FINISH);
                        intent.putExtra(EXTRA_LOCATION_DATA, SetupUtil.convertSetupInfoToLocationData(setupInfo));
                        sendBroadcast(intent);
                    } catch (Exception e) {
                        onFailure(call, e);
                    }
                }

                @Override
                public void onFailure(Call<ResponseBody> call, Throwable t) {

                }
            });
        }
    }
}
